package com.hippo.core.util;


import com.github.javafaker.Faker;
import com.github.javafaker.service.RandomService;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Constructor;
import java.util.Locale;

/**
 * 数据生成引用Faker类方法，根据反射执行Faker方法
 * @author hippo
 */
@Slf4j
public class DataGenerator {
    private final Faker faker;

    /**
     * 默认英文
     * 中文：new Locale("zh-CN")
     */
    public DataGenerator() {
        this.faker = new Faker(new Locale("zh-CN"));
    }

    /**
     * 1.自定义生成类
     * 2.默认值
     * 3.Faker方法
     */
    public Object getValueByMethodName(String packageName, String methodName, String params, String value) throws Exception {
        //customize为自定义生成类
        if ("customize".equals(packageName.split("\\.")[0])) {
            CustomizeGenerator customizeGenerate = new CustomizeGenerator();
            return customizeGenerate.main(packageName, methodName, params, value);
        }
        //当方法名为空的时候，返回默认值
        else if (methodName.length() == 0) {
            return value;
        }
        //faker方法
        else {
            try {
                //根据包名获取类实体
                Class<?> clazz = Class.forName(packageName);
                Constructor<?> declaredConstructor;
                //构造函数Constructor对象
                if ("com.github.javafaker.service.FakeValuesService".equals(packageName)) {
                    declaredConstructor = clazz.getDeclaredConstructor(Locale.class, RandomService.class);
                } else if ("com.github.javafaker.service.RandomService".equals(packageName)) {
                    declaredConstructor = clazz.getDeclaredConstructor();
                } else {
                    declaredConstructor = clazz.getDeclaredConstructor(Faker.class);
                }
                //取消Java语言访问权限检查
                declaredConstructor.setAccessible(true);
                switch (packageName) {
                    case "com.github.javafaker.service.FakeValuesService":
                        return clazz.getMethod(methodName, String.class).invoke(declaredConstructor.newInstance(Locale.CHINA, new RandomService()), value);
                    case "com.github.javafaker.service.RandomService":
                        if (params != null && params.length() != 0) {
                            if (params.split(",").length == value.split(",").length) {
                                return clazz.getMethod(methodName, int.class, int.class).invoke(declaredConstructor.newInstance(), Integer.parseInt(value.split(",")[0]), Integer.parseInt(value.split(",")[1]));
                            } else {
                                return "请输入两个整数按逗号隔开";
                            }
                        } else {
                            return clazz.getMethod(methodName).invoke(declaredConstructor.newInstance());
                        }
                    default:
                        break;
                }
                //判断该类方法中是否需要传入参数
                if (params != null && params.length() != 0) {
                    //如果有参数，需判断方法传参是否与方法参数长度相等
                    if (params.split(",").length == value.split(",").length) {
                        //参数类型为int
                        switch (params) {
                            case "int":
                                return clazz.getMethod(methodName, int.class).invoke(declaredConstructor.newInstance(faker), Integer.parseInt(value.split(",")[0]));
                            //参数类型为int,int
                            case "int,int":
                                return clazz.getMethod(methodName, int.class, int.class).invoke(declaredConstructor.newInstance(faker),
                                        Integer.parseInt(value.split(",")[0]), Integer.parseInt(value.split(",")[1]));
                            case "int,int,int":
                                return clazz.getMethod(methodName, int.class, int.class, int.class).invoke(declaredConstructor.newInstance(faker),
                                        Integer.parseInt(value.split(",")[0]), Integer.parseInt(value.split(",")[1]), Integer.parseInt(value.split(",")[2]));
                            default:
                                return "后台未定义该函数类型，请联系管理员补充";
                        }
                    } else {
                        return "未按函数要求传参，多个参数的方法，值也需要用英文逗号隔开";
                    }
                } else {
                    //方法不需要传参
                    return clazz.getMethod(methodName).invoke(declaredConstructor.newInstance(faker));
                }
            } catch (Exception e) {
                e.printStackTrace();
                //返回错误信息
                return e.toString();
            }
        }
    }
}
